package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.client.AddressClient;
import com.hmall.common.client.ItemClient;
import com.hmall.common.client.UserClient;
import com.hmall.common.pojo.Address;
import com.hmall.common.pojo.Item;
import com.hmall.common.pojo.User;
import com.hmall.order.config.SnowflakeIdGenerator;
import com.hmall.order.context.BaseContext;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.OrderVo;
import com.hmall.order.service.IOrderService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private ItemClient itemClient;
    @Autowired
    private AddressClient addressClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private SnowflakeIdGenerator snowflakeId;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 用户下单接口
     *
     * @param vo
     * @return
     */
    @Override
    @GlobalTransactional
    public String orderUser(OrderVo vo) {
        //1、基于id查询商品信息
        Long itemId = vo.getItemId();
        Integer num = vo.getNum();
        Item item = this.itemClient.getbyId(itemId);
        //1.2、计算商品总价，封装Order对象
        Long sum =  item.getPrice() * num;
        //雪花算法id
        long logisticsNumber = this.snowflakeId.nextId();
        //用户id
        Long userId = BaseContext.getCurrentId();
        Order order = Order.builder()
                .totalFee(sum)
                .paymentType(1)
                .userId(userId)
                .status(1)
                .createTime(new Date())
                .build();
        //1.3、写入tb_order数据表
        this.orderMapper.insert(order);
        Long orderId = order.getId();
        //2、封装OrderDetail对象，写入tb_order_detail表
        OrderDetail orderDetail = OrderDetail.builder()
                .orderId(orderId)
                .itemId(item.getId())
                .num(num)
                .name(item.getName())
                .price(item.getPrice())
                .spec(item.getSpec())
                .image(item.getImage())
                .createTime(new Date())
                .build();
        orderDetailMapper.insert(orderDetail);
        //2.2、基于地址id查询地址信息
        Address address = addressClient.findAddressById(Long.valueOf(vo.getAddressId()));
        //2.3、封装OrderLogistics对象，写入tb_order_logistics表
        //2.4、用户id查询用户信息
        User user = userClient.getById(userId);
        String orderNumber = String.valueOf(logisticsNumber).substring(0,15);
        OrderLogistics orderLogistics = OrderLogistics.builder()
                .orderId(orderId)
                .logisticsNumber(orderNumber)
                .logisticsCompany("德邦大件物流")
                .contact(user.getUsername())
                .mobile(user.getPhone())
                .province(address.getProvince())
                .city(address.getCity())
                .town(address.getTown())
                .street(address.getStreet())
                .createTime(new Date())
                .build();
        orderLogisticsMapper.insert(orderLogistics);
        //3、扣减item服务的库存信息
        itemClient.updateStock(itemId,num);

        //4、发送超时未支付取消请求
        //4.1、 创建消息
        Message message = MessageBuilder
                .withBody(orderId.toString().getBytes())
                .setHeader("x-delay",60000)
                .build();
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        //4.2、 发送消息
        rabbitTemplate.convertAndSend("cxk.direct", "ttl", message, correlationData);
        //4.3、 记录日志
        log.debug("发送消息成功");
        return "下单成功";
    }
}
